home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume12 / cnews / part08 < prev    next >
Encoding:
Internet Message Format  |  1987-10-21  |  50.5 KB

  1. Subject:  v12i033:  C News alpha release, Part08/14
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: utzoo!henry (Henry Spencer)
  7. Posting-number: Volume 12, Issue 33
  8. Archive-name: cnews/part08
  9.  
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 8 (of 14)."
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f 'README.SECOND' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'README.SECOND'\"
  21. else
  22. echo shar: Extracting \"'README.SECOND'\" \(5898 characters\)
  23. sed "s/^X//" >'README.SECOND' <<'END_OF_FILE'
  24. XC news is a replacement for most of B news with much better performance.
  25. XSee our paper in the winter 1987 Usenix for some details of how.
  26. X
  27. XC news does not include an all-singing-all-dancing news reader.  We think
  28. XLarry Wall's rn is the reader of choice.  There are others.  We have no
  29. Xdesire to write one ourselves.
  30. X
  31. XWe have included the Australian readnews (with permission) as a simple
  32. Xnews reader, for those who wish to dispense with B news completely.
  33. XNote that we have changed it a bit and bugs should be assumed to be our
  34. Xfault not Michael Rourke's.
  35. X
  36. XFor those who have run one of our ancient pre-beta versions, many things
  37. Xhave changed, and in particular the four-field history file format is gone.
  38. X
  39. XSpeaking of file formats...
  40. X
  41. XThe active file format is the 4-field one that B news introduced midway
  42. Xthrough 2.10, unchanged.
  43. X
  44. XThe history file format is like B with one exception:  the second field,
  45. Xwhich few programs ever look at, now consists of two subfields separated
  46. Xby a tilde (~).  The first is the arrival date as a decimal number, the
  47. Xsecond is the expiry date (if any) as a human-readable date (as emitted by
  48. Xrnews) or a decimal number (after expire has gotten its hands on it once).
  49. XExpire is tolerant of human-readable dates in both those places, but other
  50. Xthings may not be.  The best way to get the history file into the new
  51. Xformat is to rebuild it completely (this is RELATIVELY quick).
  52. X
  53. XThe sys file format is like a late-model B news with two extensions.  First,
  54. Xthe second field (groups and distributions) may optionally be split into
  55. Xtwo subfields (newsgroups and distributions, respectively) with a slash.
  56. XThis permits solutions to various tricky problems that can arise in odd
  57. Xsituations if it is impossible to tell what's a newsgroup name and what's
  58. Xa distribution.  Second, there is a new flag in the third field:  f is like
  59. XF except that its output has the size information that the C batcher
  60. Xwants for accurate limiting of batch size.  (Incidentally, note a limitation,
  61. Xone that will be fixed in the definitive release:  with both f and F, having
  62. Xthe same filename in more than one sys-file line is, uh, a bad idea.  The
  63. Xbatcher is flexible enough to get around most needs for this.)
  64. X
  65. XThe way the news articles themselves are stored is totally unchanged; we
  66. Xhave been unable to think of any changes that are worth the trouble.
  67. X
  68. XFinally, there is a new control file, conventionally named
  69. X/usr/lib/news/explist, which is expire's control file (see the expire
  70. Xmanual page) (pre-alpha sites, note that the format has changed).
  71. X
  72. XFile organization:  the one change is that programs are now kept mostly in
  73. X/usr/lib/newsbin, with /usr/lib/news reserved for control files etc.  Most
  74. X(by intent all) of the programs understand four key environment variables:
  75. XNEWSARTS specifies location of articles (default /usr/spool/news), NEWSCTL
  76. Xspecifies location of control files (default /usr/lib/news), NEWSBIN gives
  77. Xlocation of programs (default /usr/lib/newsbin), and NEWSUMASK gives the
  78. Xumask to be used in creating files (default 002).  The environment variables
  79. Xoverride the defaults for testing and for operation in funny situations.
  80. XNote that one or two things (e.g. relaynews), as distributed, will insist
  81. Xon renouncing setuid privileges if invoked with these overrides.
  82. X
  83. XC news is divided into various subsystems, each occupying a directory
  84. Xof its own.
  85. X
  86. XTwo directories -- include and libcnews -- are support stuff (respectively
  87. Xinclude files and library functions) used by most of the subsystems.
  88. X
  89. XThe libc directory contains stuff that is in our C libraries but might not
  90. Xbe in yours.
  91. X
  92. XThe input spooler, which accepts incoming news batches and spools them
  93. Xup for later processing, is in directory input.  Be warned:  it does do one
  94. Xessential function other than spooling -- it strips the stupid "#! cunbatch"
  95. Xheader off 2.11-style batches.  It includes the "rnews" program that goes
  96. Xin /bin (or /usr/bin, or wherever); "rnews" and "cunbatch" are identical
  97. Xin C news.
  98. X
  99. XThe output batcher is in directory batch.  It will work with B news as well,
  100. Xalthough not as well (it really wants to be told the size of an article as
  101. Xwell as its name).
  102. X
  103. XExpire and its friends, including history rebuilding and active-file updating
  104. X(neither of which are done by expire itself in C news) are in directory
  105. Xexpire.
  106. X
  107. Xgngp contains a grep-like program which matches newsgroups, used in inews
  108. Xamong other things.
  109. X
  110. Xtime contains a couple of small programs occasionally useful in maintaining
  111. Xthe history file with its numeric dates -- ctime converts numeric to human
  112. Xand getdate goes the other way.
  113. X
  114. Xnewshist contains a maintenance program which accepts a news message-ID
  115. Xand prints the history line for that article.
  116. X
  117. Xmail contains various bits of software for shipping news via mail, both
  118. Xcleaner and faster than uurec et al.
  119. X
  120. Xlib.proto is a sort of prototype /usr/lib/news containing some useful things
  121. X(notably newsboot, which should be run from /etc/rc on reboot) and some old
  122. Xunnecessary trash (probably).  newsbin.proto is similar for /usr/lib/newsbin.
  123. X
  124. Xrna is the Australian readnews, plus other odds and ends of their software
  125. Xthat we haven't sorted through yet.
  126. X
  127. XAnd rnews is the Augean Stables themselves (read RFC850 if you don't believe
  128. Xus):  the news-relaying software, containing most of the work and most of
  129. Xthe speedup.  Various auxiliaries, sped-up versions of libraries, and other
  130. Xthings proliferate underneath this directory.  Of note is setnewsids, a little
  131. Xsetuid-root (gasp!) program needed on systems which do not permit the
  132. Xsetuid(geteuid()) operation, to make relaynews run with the right ownerships.
  133. XNote, by the way, that the only program now named "rnews" is the one in
  134. Xthe input subsystem, although programs with various related names live under
  135. Xthe rnews directory.  This was a late change, removing much previous
  136. Xconfusion but perhaps creating some of its own.
  137. END_OF_FILE
  138. if test 5898 -ne `wc -c <'README.SECOND'`; then
  139.     echo shar: \"'README.SECOND'\" unpacked with wrong size!
  140. fi
  141. # end of 'README.SECOND'
  142. fi
  143. if test -f 'batch/newsbatch.8.p' -a "${1}" != "-c" ; then 
  144.   echo shar: Will not clobber existing file \"'batch/newsbatch.8.p'\"
  145. else
  146. echo shar: Extracting \"'batch/newsbatch.8.p'\" \(5897 characters\)
  147. sed "s/^X//" >'batch/newsbatch.8.p' <<'END_OF_FILE'
  148. X.TH NEWSBATCH 8 local
  149. X.DA 11 Aug 1987
  150. X.SH NAME
  151. Xsendbatches, batchmake, batchmunch \- news batching to other sites
  152. X.br
  153. Xbatchprep, batchsize, batchxmit \- news batching to other sites
  154. X.br
  155. Xqueuelen, queuemax, roomfor \- news batching to other sites
  156. X.SH SYNOPSIS
  157. X.B $NEWSBIN/batch/sendbatches
  158. X[
  159. X.B \-c
  160. X]
  161. X[ name ... ]
  162. X.PP
  163. X.B \&.../batchmake
  164. X[
  165. X.B \-d
  166. Xdirectory
  167. X]
  168. Xlistfile
  169. X.br
  170. X.B \&.../batchmunch
  171. X.br
  172. X.B \&.../batchprep
  173. Xbatchsize
  174. X.br
  175. X.B \&.../batchsize
  176. X.br
  177. X.B \&.../batchxmit
  178. Xsite
  179. X.br
  180. X.B \&.../queuelen
  181. Xsite
  182. X.br
  183. X.B \&.../queuemax
  184. X.br
  185. X.B \&.../roomfor
  186. Xbatchsize
  187. X.SH DESCRIPTION
  188. X.I Sendbatches
  189. Xadministers batched transmission of news to other sites.
  190. XIt should be run periodically, under userid \fInews\fR,
  191. Xby \fIcron\fR(8) or similar means.
  192. XIt prepares and sends batches of news,
  193. Xsubject to restrictions on available space and length of outbound queues.
  194. X.PP
  195. X\fISendbatches\fR and all its auxiliaries recognize the standard
  196. Xenvironment variables \fB$\&NEWSARTS\fR,
  197. X\fB$\&NEWSCTL\fR, \fB$\&NEWSBIN\fR, and \fB$NEWSUMASK\fR
  198. Xwhich indicate, respectively, non-default locations
  199. Xfor news articles, news control files, and news programs,
  200. Xand a non-default \fIumask\fR (see \fIumask\fR(2)) for file creation
  201. X(the default \fIumask\fR is 002).
  202. X.PP
  203. XEach site that can have batches sent to it needs a \fBb.\fIsite\fR directory
  204. Xunder \fI$\&NEWSCTL/batch\fR.
  205. XBy default \fIsendbatches\fR considers preparation of batches for all
  206. Xsites that have such a directory, in order as given
  207. Xby the \fIsites\fR file (see below).
  208. XIf \fIsendbatches\fR
  209. Xis invoked with \fInames\fR of specific sites, it considers only those
  210. Xsites as candidates for batching, in the order given.
  211. XIf it is invoked with a
  212. X.B \-c
  213. Xoption, the \fInames\fR are classes of sites, which are considered
  214. Xin the order given,
  215. Xwith order within each class set by order in the \fIsites\fR file.
  216. X.PP
  217. XIf there is a \fI$\&NEWSCTL/batch/sites\fR file, it controls ordering of sites
  218. Xand assignment of sites into classes.
  219. XEach line consists of one or more white-space-separated fields,
  220. Xthe first being a site name, and the rest
  221. X(if any)
  222. Xbeing names of classes to which
  223. Xthat site belongs.
  224. XBlank lines and lines beginning with `#' are ignored.
  225. XThe order of lines determines the default order of \fIsendbatches\fR
  226. Xprocessing, with any unmentioned sites going last.
  227. XIf there is no \fIsites\fR file, classes cannot be used and the default
  228. Xsite ordering is alphabetical.
  229. X.PP
  230. XTo use the batcher, names of files to be sent to a specific site should
  231. Xbe appended to a \fItogo\fR file in its \fBb.\fIsite\fR directory.
  232. XThe batcher expects the lines in \fItogo\fR to have two fields, a filename
  233. X(as a full pathname) of an article and its size in bytes.
  234. XA missing size field is arbitrarily assumed to be a default average.
  235. X.PP
  236. X\fISendbatches\fR uses a number of auxiliary programs to do the real work.
  237. XThe search path it uses to find them includes, in order,
  238. Xthe \fBb.\fIsite\fR directory for the site in question,
  239. X\fI$\&NEWSCTL/batch\fR, and \fI$\&NEWSBIN/batch\fR.
  240. XThis permits per-site and per-news-database overrides of the default
  241. Xbehaviors.
  242. X\fISendbatches\fR provides all these programs with an environment
  243. Xvariable \fB$NEWSSITE\fR, containing the name of the site that batches
  244. Xare being prepared for, in case this is useful in customization.
  245. X.PP
  246. XFor each site being considered for batches, \fIsendbatches\fR first
  247. Xdetermines whether there are in fact any articles to be batched.
  248. XAssuming there are, \fIsendbatches\fR then invokes \fIqueuelen\fR
  249. Xto find out how many batches are in the outbound queue for
  250. Xthe site, \fIqueuemax\fR to find out how long queues are allowed to be,
  251. X\fIbatchsize\fR to determine how big batches should be (in bytes),
  252. Xand \fIroomfor\fR
  253. Xto determine how many batches of that size will fit without depleting the
  254. Xavailable spool space too much.
  255. X\fISendbatches\fR limits the number of batches prepared to the minimum of
  256. Xthe limits implied by queue lengths and available space.
  257. X.PP
  258. X\fISendbatches\fR uses \fIbatchprep\fR
  259. Xas necessary
  260. Xto slice chunks out of the \fItogo\fR
  261. Xfile, each chunk containing the
  262. X\fItogo\fR lines for a batch limited to the specified size.
  263. XException:  a single article bigger than the specified size will still go out
  264. Xas one batch.
  265. X.PP
  266. XEach chunk is then processed through \fIbatchmake\fR, which assembles the
  267. Xarticles into a batch, \fIbatchmunch\fR, which performs auxiliary processing
  268. X(e.g. data compression), and \fIbatchxmit\fR,
  269. Xwhich sends the batch on its way (e.g. enqueues it for transmission).
  270. XIf \fIbatchmake\fR is invoked with a \fB\-d\fR option, it \fIchdir\fRs to
  271. Xthe \fIdirectory\fR first, and strips it off the beginning of any article
  272. Xfilename that starts with it.
  273. XSince most articles will come from \fI$\&NEWSARTS\fR, specifying
  274. X\fB\-d\ $\&NEWSARTS\fR to \fIbatchmake\fR will speed it up noticeably.
  275. X.PP
  276. X\fISendbatches\fR logs some information about sites with backlogs in
  277. X\fI$\&NEWSCTL/batchlog\fR, keeping the previous \fIbatchlog\fR in
  278. X\fIbatchlog.o\fR and the one before that in \fIbatchlog.oo\fR.
  279. XThis is intended to help detection and diagnosis of flow problems.
  280. X.SH FILES
  281. X.ta \w'/usr/lib/news/LOCKbatch*'u+3n
  282. X.nf
  283. X/usr/lib/news/LOCKbatch    lock for \fIsendbatches\fR
  284. X/usr/lib/news/LOCKbatch*    lock temporaries
  285. X/usr/lib/news/LOCK    overall news lock (used by \fIbatchprep\fR)
  286. X/usr/lib/news/LOCKTM*    lock temporaries
  287. X/usr/spool/news    default \fB$\&NEWSARTS\fR
  288. X/usr/lib/news    default \fB$\&NEWSCTL\fR
  289. X/usr/lib/newsbin    default \fB$\&NEWSBIN\fR
  290. X$NEWSARTS    local \fB$\&NEWSARTS\fR
  291. X$NEWSCTL    local \fB$\&NEWSCTL\fR
  292. X$NEWSBIN    local \fB$\&NEWSBIN\fR
  293. X
  294. Xalso see text
  295. X.SH SEE ALSO
  296. Xinews(1), compress(1), uux(1)
  297. X.SH HISTORY
  298. XWritten at University of Toronto as part of the C News project.
  299. X.SH BUGS
  300. X\fIBatchprep\fR does not count the `#!\ rnews\ \fInnnn\fR' headers inside
  301. Xbatches when computing batch lengths.
  302. X.PP
  303. X\fIBatchprep\fR arguably should be smarter about determining file sizes
  304. Xin the absence of counts in the \fItogo\fR file.
  305. END_OF_FILE
  306. if test 5897 -ne `wc -c <'batch/newsbatch.8.p'`; then
  307.     echo shar: \"'batch/newsbatch.8.p'\" unpacked with wrong size!
  308. fi
  309. # end of 'batch/newsbatch.8.p'
  310. fi
  311. if test -f 'libcnews/ngmatch.c' -a "${1}" != "-c" ; then 
  312.   echo shar: Will not clobber existing file \"'libcnews/ngmatch.c'\"
  313. else
  314. echo shar: Extracting \"'libcnews/ngmatch.c'\" \(5712 characters\)
  315. sed "s/^X//" >'libcnews/ngmatch.c' <<'END_OF_FILE'
  316. X/*
  317. X * ngmatch - newsgroup name matching
  318. X */
  319. X
  320. X#include <stdio.h>
  321. X#include <sys/types.h>
  322. X#include "news.h"
  323. X
  324. X#define truth(bool) ((bool)? "yes": "no")
  325. X
  326. X#ifndef STATIC
  327. X#define STATIC /* static */
  328. X#endif
  329. X
  330. X#define ALL "all"            /* word wildcard */
  331. X
  332. Xstatic int debug = NO;
  333. X
  334. Xmatchdebug(state)
  335. Xint state;
  336. X{
  337. X    debug = state;
  338. X}
  339. X
  340. X/*
  341. X * ngmatch returns true iff the newsgroup(s) in ngs match
  342. X * the pattern(s) in ngpat, where
  343. X *
  344. X *     ngpats: { ngpat { "," ngpat }* }?
  345. X *    ngpat: "!"? word { "." word }*
  346. X *    word: { alphanum }+ | "all"
  347. X *
  348. X * Only one group need match for success.  (Redundant?)
  349. X *
  350. X * For each group, note the depth of each match against the patterns,
  351. X * negated or not.  Ignore mismatches.  The deepest match wins at the end;
  352. X * if it's a tie, negated matches are rejections.
  353. X *
  354. X * A match of any group against the patterns is a success.
  355. X * Failure to match any pattern with a group is a mismatch of that group.
  356. X * Failure to match any group against any pattern is a total failure.
  357. X *
  358. X * "all" in a pattern is a wildcard that matches exactly one word;
  359. X * it does not cross "." (NGDELIM) delimiters.
  360. X */
  361. X
  362. Xint
  363. Xngmatch(ngpat, ngs)
  364. Xchar *ngpat, *ngs;
  365. X{
  366. X    register char *ngp;            /* point at current group */
  367. X    register char *ngcomma;
  368. X    register char *rngpat = ngpat;
  369. X
  370. X    if (debug)
  371. X        (void) fprintf(stderr, "ngmatch(`%s', `%s')\n", rngpat, ngs);
  372. X    for (ngp = ngs; ngp != NULL; ngp = ngcomma) {
  373. X        register int match;
  374. X
  375. X        INDEX(ngp, NGSEP, ngcomma);
  376. X        if (ngcomma != NULL)
  377. X            *ngcomma = '\0';    /* will be restored below */
  378. X        match = mpatsmatch(rngpat, ngp);    /* try 1 group, multi-patterns */
  379. X        if (ngcomma != NULL)
  380. X            *ngcomma++ = NGSEP;    /* point after the comma */
  381. X        if (match)
  382. X            return YES;
  383. X    }
  384. X    return NO;                /* no pattern matched any group */
  385. X}
  386. X
  387. X/*
  388. X * Match one group against multiple patterns, as above.
  389. X */
  390. XSTATIC int
  391. Xmpatsmatch(ngpat, grp)
  392. Xchar *ngpat, *grp;
  393. X{
  394. X    register char *patp;        /* point at current pattern */
  395. X    register char *patcomma;
  396. X    register int depth;
  397. X    register int faildeepest = 0, hitdeepest = 0;    /* in case of no match */
  398. X    register int negation;
  399. X
  400. X    if (debug)
  401. X        (void) fprintf(stderr, "mpatsmatch(`%s', `%s')\n", ngpat, grp);
  402. X    for (patp = ngpat; patp != NULL; patp = patcomma) {
  403. X        negation = 0;
  404. X        INDEX(patp, NGSEP, patcomma);
  405. X        if (patcomma != NULL)
  406. X            *patcomma = '\0';    /* will be restored below */
  407. X        if (*patp == NGNEG) {
  408. X            ++patp;
  409. X            ++negation;
  410. X        }
  411. X        depth = onepatmatch(patp, grp);    /* try 1 pattern, 1 group */
  412. X        if (patcomma != NULL)
  413. X            *patcomma++ = NGSEP;    /* point after the comma */
  414. X        if (depth == 0)            /* mis-match */
  415. X            ;            /* ignore it */
  416. X        else if (negation) {
  417. X            /* record ordinal # of deepest negated matched word */
  418. X            if (depth > faildeepest)
  419. X                faildeepest = depth;
  420. X        } else {
  421. X            /* record ordinal # of deepest plain matched word */
  422. X            if (depth > hitdeepest)
  423. X                hitdeepest = depth;
  424. X        }
  425. X    }
  426. X    if (debug)
  427. X        (void) fprintf(stderr, "mpatsmatch(`%s', `%s') returns %s\n",
  428. X            ngpat, grp, truth(hitdeepest > faildeepest));
  429. X    return hitdeepest > faildeepest;
  430. X}
  431. X
  432. X/*
  433. X * Match a pattern against a group by looking at each word of pattern in turn.
  434. X *
  435. X * On a match, return the ordinal number of the rightmost word that matches.
  436. X * If group runs out first, the match fails; else it succeeds.
  437. X * On a failure, return zero.
  438. X */
  439. XSTATIC int
  440. Xonepatmatch(patp, grp)            /* match 1 pattern vs 1 group */
  441. Xchar *patp, *grp;
  442. X{
  443. X    register char *rpatwd;        /* used by word match (inner loop) */
  444. X    register char *patdot, *grdot;    /* point at dots after words */
  445. X    register char *patwd, *grwd;    /* point at current words */
  446. X    register int depth = 0;
  447. X
  448. X    for (patwd = patp, grwd = grp; patwd != NULL && grwd != NULL;
  449. X        patwd = patdot, grwd = grdot, depth++) {
  450. X        register int match;
  451. X
  452. X            /* null-terminate words */
  453. X            INDEX(patwd, NGDELIM, patdot);
  454. X        if (patdot != NULL)
  455. X            *patdot = '\0';        /* will be restored below */
  456. X            INDEX(grwd, NGDELIM, grdot);
  457. X        if (grdot != NULL)
  458. X            *grdot = '\0';        /* will be restored below */
  459. X
  460. X        /*
  461. X         * Match one word of pattern with one word of group.
  462. X         * A pattern word of "all" matches any group word.
  463. X         */
  464. X#ifdef FAST_STRCMP
  465. X        match = STREQ(patwd, grwd) || STREQ(patwd, ALL);
  466. X#else
  467. X        match = NO;
  468. X        for (rpatwd = patwd; *rpatwd == *grwd++; )
  469. X            if (*rpatwd++ == '\0') {
  470. X                match = YES;        /* literal match */
  471. X                break;
  472. X            }
  473. X        if (!match) {
  474. X            /* ugly special case match for "all" */
  475. X            rpatwd = patwd;
  476. X            match = *rpatwd++ == 'a' && *rpatwd++ == 'l' &&
  477. X                    *rpatwd++ == 'l' && *rpatwd   == '\0';
  478. X        }
  479. X#endif                /* FAST_STRCMP */
  480. X
  481. X        if (patdot != NULL)
  482. X            *patdot++ = NGDELIM;    /* point after the dot */
  483. X        if (grdot != NULL)
  484. X            *grdot++ = NGDELIM;
  485. X        if (!match) {
  486. X            depth = 0;        /* words differed - mismatch */
  487. X            break;
  488. X        }
  489. X    }
  490. X    /* if group name ran out before pattern, then match fails */
  491. X    if (grwd == NULL && patwd != NULL)
  492. X        depth = 0;
  493. X    if (debug)
  494. X        (void) fprintf(stderr, "onepatmatch(`%s', `%s') returns %d\n",
  495. X            patp, grp, depth);
  496. X    return depth;
  497. X}
  498. X
  499. X#ifdef CROSS_POSTINGS_RESTRICTED
  500. X/*
  501. X * ngtopsame(ngs) - true iff ngs are all in the same top-level distribution
  502. X */
  503. Xint
  504. Xngtopsame(ngs)
  505. Xregister char *ngs;
  506. X{
  507. X    register char *nextng;
  508. X
  509. X    INDEX(ngs, NGSEP, nextng);
  510. X    if (nextng == NULL)        /* no groups left */
  511. X        return YES;
  512. X    ++nextng;            /* skip NGSEP */
  513. X    return firstsame(ngs, nextng) && ngtopsame(nextng);
  514. X}
  515. X
  516. X/*
  517. X * firstsame(ng1, ng2) - true iff first characters (up to the first
  518. X * NGDELIM or NGSEP) are the same in each string.  Neither string
  519. X * is guaranteed to be null-terminated (a small lie; one *is*).
  520. X */
  521. XSTATIC int
  522. Xfirstsame(ng1, ng2)
  523. Xregister char *ng1, *ng2;
  524. X{
  525. X    register int ng1brk;
  526. X    static char delimstr[] = { NGSEP, NGDELIM, '\0' };
  527. X    extern int strcspn();
  528. X
  529. X    ng1brk = strcspn(ng1, delimstr);
  530. X    return ng1brk == strcspn(ng2, delimstr) && STREQN(ng1, ng2, ng1brk);
  531. X}
  532. X#endif
  533. END_OF_FILE
  534. if test 5712 -ne `wc -c <'libcnews/ngmatch.c'`; then
  535.     echo shar: \"'libcnews/ngmatch.c'\" unpacked with wrong size!
  536. fi
  537. # end of 'libcnews/ngmatch.c'
  538. fi
  539. if test -f 'rna/man/postnews.1' -a "${1}" != "-c" ; then 
  540.   echo shar: Will not clobber existing file \"'rna/man/postnews.1'\"
  541. else
  542. echo shar: Extracting \"'rna/man/postnews.1'\" \(5207 characters\)
  543. sed "s/^X//" >'rna/man/postnews.1' <<'END_OF_FILE'
  544. X.TH POSTNEWS 1
  545. X.SH NAME
  546. Xpostnews \- submit news articles
  547. X.SH SYNOPSIS
  548. X.B postnews
  549. X.RB [ -h ]
  550. X.RB [ -s
  551. Xsubject]
  552. X.RB [ -n
  553. Xnewsgroups]
  554. X.RB [ -d
  555. Xdistribution]
  556. X.br
  557. X.in +9
  558. X.RB [ -e
  559. Xexpiredate ..]
  560. X.RB [ -r
  561. Xreferences]
  562. X.RB [ -i
  563. Xinterpfile]
  564. X.br
  565. X.in -9
  566. X.P
  567. X.B postnews
  568. X.B -c
  569. Xcontrol_command
  570. X.RB [ -n
  571. Xnewsgroups]
  572. X.RB [ -d
  573. Xdistribution]
  574. X.br
  575. X.P
  576. X.B postnews
  577. X.B -p
  578. X.SH DESCRIPTION
  579. X.I Postnews
  580. Xsubmits news articles to the network news system.
  581. XNormally
  582. X.I postnews
  583. Xis used interactively, in which case no arguments are required,
  584. Xand
  585. X.I postnews
  586. Xwill prompt the user for the subject, newsgroup and distribution
  587. Xfields.
  588. XIf any other fields are required they must be specified on the command
  589. Xline.
  590. XThe article text may then be entered, and may be terminated by a `.' or EOT.
  591. XLike
  592. X.IR mail (1),
  593. Xcommands are available while entering an article, to escape to an
  594. Xeditor, interpolate the current article or run a shell command.
  595. X.P
  596. XThe second two forms of the
  597. X.B postnews
  598. Xcommand are for news administration use only.
  599. X.I Postnews
  600. Xis often called by
  601. X.IR readnews (1)
  602. Xto post follow-up articles, and post new articles;
  603. Xmany flag arguments are provided for this purpose.
  604. X.P
  605. XOptional flags are:
  606. X.TP
  607. X.B -h
  608. Xis used when input is redirected from a file containing an article.
  609. XIt specifies that headers are present at the beginning of the article,
  610. Xand that these headers should be included with the article header instead
  611. Xof as text.
  612. XOnly headers the user may set are permitted.
  613. X.TP
  614. X\fB-s \fIsubject\fR
  615. Xspecifies the subject of the article.
  616. XIf it is not specified in this way it must be specified interactively.
  617. XThis must be carefully chosen to be brief yet descriptive.
  618. X.TP
  619. X\fB-n \fInewsgroups\fR
  620. Xspecifies a comma separated list of newsgroups to which the article
  621. Xwill be posted.
  622. XThe default is
  623. X.BR general .
  624. X.TP
  625. X\fB-d \fIdistribution\fR
  626. Xusually not specified, is the same format as a newsgroup,
  627. Xand is used to restrict the article's distribution to those
  628. Xhosts which subscribe to the group(s) specified.
  629. X.TP
  630. X\fB-e \fIexpiredate\fR ..
  631. Xspecifies a date for the article to expire (instead of the usual default).
  632. XThe format of the date arguments are as follows:
  633. X.RS 5
  634. X.TP 14
  635. X.IR day :
  636. X(
  637. X.I dayofweek
  638. X[ 
  639. X.B week
  640. X] ) |
  641. X.BR 1 .. 31
  642. X.RS 2
  643. X.TP 14
  644. X.IR dayofweek :
  645. X.B sunday
  646. X| ... | 
  647. X.B saturday
  648. X|
  649. X.B tomorrow
  650. X|
  651. X.B today
  652. X.RE
  653. X.TP
  654. X.IR month :
  655. X.B january
  656. X| ... | 
  657. X.B december
  658. X.TP
  659. X.IR year :
  660. X.BR 1970 .. 2038
  661. X.RE
  662. X.P
  663. X.RS 5
  664. XThe arguments
  665. X.I day
  666. X,
  667. X.I month
  668. Xand
  669. X.I year
  670. Xare order-independent,
  671. Xand words may be shortened to a non-ambiguous abbreviation.
  672. X.P
  673. XAs the time must be in the future, unspecified
  674. X.I day
  675. X,
  676. X.I month
  677. Xand
  678. X.I year
  679. Xarguments default to the `next' day, month or year as necessary;
  680. Xotherwise the current day, month and year are used.
  681. X.P
  682. X.RE
  683. X.TP
  684. X\fB-r \fIreferences\fR
  685. Xusually used by
  686. X.IR readnews (1)
  687. Xwhen posting a followup article.
  688. X.I references
  689. Xcontain the message-id of the article being followed up.
  690. X.TP
  691. X\fB-i \fIinterpfile\fR
  692. Xusually used by
  693. X.IR readnews (1)
  694. Xwhen posting a followup article.
  695. X.I interpfile
  696. Xis the file available to the `.i' command when entering an
  697. Xarticle interactively.
  698. X.TP
  699. X\fB-c \fIcontrol_command\fR
  700. Xspecifies special control commands.
  701. XCommands are
  702. X\fR`\fBnewgroup \fIgroupname\fR'
  703. Xto create a new newsgroup (news admin only)
  704. Xand
  705. X\fR`\fBcancel \fImessageid\fR'
  706. Xto cancel a message (sender or news admin only).
  707. XNewsgroups and distribution may be specified to
  708. Xlimit the scope of the control command.
  709. X.TP
  710. X.B -p
  711. Xindicates the article on standard input has come from
  712. Xanother host (and contains headers etc.) - news admin only.
  713. X.P
  714. XWhen entering an article interactively,
  715. Xa
  716. X.RB \&' . '
  717. Xor EOT
  718. Xby itself on a line terminates entering and posts the article.
  719. XOther commands are available:
  720. X.TP
  721. X\&\fB.e\fR
  722. XEdit the article collected so far (see
  723. X.IR ed (1)).
  724. XAfter editing further lines may be appended to the article.
  725. X.TP
  726. X\&\fB.i\fR
  727. XInterpolate
  728. Xthe file specified by the
  729. X.B -i
  730. Xflag
  731. Xonto the end of the message. The interpolated item
  732. Xis indented by four spaces.
  733. X.TP
  734. X\&\fB.!\fIcmd\fR or \fB!\fIcmd\fR
  735. XShell escape.
  736. X.IR Cmd
  737. Xis executed.
  738. X.TP
  739. X.B DEL
  740. XCauses posting to be aborted, and the article entered so far
  741. Xis saved in
  742. X.BR $HOME/dead.article .
  743. X.P
  744. XWhen posting an article, the environment is checked for information
  745. Xabout the sender.
  746. XIf
  747. X.B NAME
  748. Xis found,
  749. Xits value is used for the full name, rather than the system value
  750. X(found in
  751. X.BR /etc/passwd ).
  752. XIf
  753. X.B ORGANIZATION
  754. Xis found,
  755. Xthe value overrides the system default organization.
  756. XAn alternative editor (for the
  757. X.B .e
  758. Xcommand) may be used by setting
  759. X.B EDITOR
  760. Xin the environment.
  761. X.P
  762. XAfter local installation of the article,
  763. X.I postnews
  764. Xwill transmit the article to all systems that subscribe to the
  765. Xnewsgroups that the articles belong to.
  766. X.SH FILES
  767. X.ta 24
  768. X.nf
  769. X/usr/lib/news/active    current newsgroups
  770. X/usr/lib/news/seq    contains next sequence number
  771. X/usr/lib/news/history    messageids of all articles received
  772. X/usr/lib/news/sys    subscriptions lists for other hosts
  773. X%news        where the articles are kept
  774. X%news/itmp*    temporary articles
  775. X$HOME/dead.article    saved article when aborted
  776. X.fi
  777. X.SH SEE ALSO
  778. Xreadnews(1), mail(1), uusend(8), uurec(8).
  779. X.SH BUGS
  780. XThe headers can't be altered by using the `.e' command.
  781. X.SH AUTHOR
  782. XMichael Rourke, University of N.S.W. (decvax!mulga!michaelr:elecvax)
  783. END_OF_FILE
  784. if test 5207 -ne `wc -c <'rna/man/postnews.1'`; then
  785.     echo shar: \"'rna/man/postnews.1'\" unpacked with wrong size!
  786. fi
  787. # end of 'rna/man/postnews.1'
  788. fi
  789. if test -f 'rna/readnews.lint' -a "${1}" != "-c" ; then 
  790.   echo shar: Will not clobber existing file \"'rna/readnews.lint'\"
  791. else
  792. echo shar: Extracting \"'rna/readnews.lint'\" \(5157 characters\)
  793. sed "s/^X//" >'rna/readnews.lint' <<'END_OF_FILE'
  794. Xheader.c(126): warning: possible pointer alignment problem
  795. X
  796. Xreadnews.c(268): warning: possible pointer alignment problem
  797. Xreadnews.c(269): warning: possible pointer alignment problem
  798. Xreadnews.c(345): warning: com set but not used in function subs
  799. Xreadnews.c(953): warning: possible pointer alignment problem
  800. Xreadnews.c(1256): warning: possible pointer alignment problem
  801. Xreadnews.c(1256): warning: possible pointer alignment problem
  802. X
  803. Xfuncs.c(232): warning: long assignment may lose accuracy
  804. X
  805. Xactive.c(103): warning: possible pointer alignment problem
  806. X
  807. Xnewsrc.c(82): warning: possible pointer alignment problem
  808. Xnewsrc.c(90): warning: possible pointer alignment problem
  809. Xnewsrc.c(115): warning: possible pointer alignment problem
  810. Xnewsrc.c(153): warning: possible pointer alignment problem
  811. X
  812. Xhistory.c(109): warning: possible pointer alignment problem
  813. Xhistory.c(120): warning: possible pointer alignment problem
  814. Xhistory.c(172): warning: long assignment may lose accuracy
  815. Xhistory.c(172): warning: long assignment may lose accuracy
  816. X
  817. Xmaketime.c(413): warning: long assignment may lose accuracy
  818. Xmaketime.c(413): warning: long assignment may lose accuracy
  819. Xmaketime.c(413): warning: long assignment may lose accuracy
  820. Xmaketime.c(444): warning: long assignment may lose accuracy
  821. Xmaketime.c(444): warning: long assignment may lose accuracy
  822. Xmaketime.c(445): warning: long assignment may lose accuracy
  823. Xmaketime.c(445): warning: long assignment may lose accuracy
  824. X
  825. Xsprintf value declared inconsistently    llib-lc:llib-lc(287)  ::  header.c(469)
  826. X
  827. Xqsort, arg. 2 used inconsistently    llib-lc:llib-lc(210)  ::  readnews.c(132)
  828. Xapply, arg. 3 used inconsistently    newsrc.c(138)  ::  readnews.c(144)
  829. Xapply, arg. 3 used inconsistently    newsrc.c(138)  ::  readnews.c(146)
  830. Xapply, arg. 3 used inconsistently    newsrc.c(138)  ::  readnews.c(154)
  831. Xwait, arg. 1 used inconsistently    llib-lc:llib-lc(138)  ::  readnews.c(1163)
  832. Xqsort, arg. 2 used inconsistently    llib-lc:llib-lc(210)  ::  readnews.c(1265)
  833. Xsprintf value declared inconsistently    llib-lc:llib-lc(287)  ::  readnews.c(859)
  834. X
  835. Xsprintf value declared inconsistently    llib-lc:llib-lc(287)  ::  funcs.c(238)
  836. X
  837. Xerror defined( maketime.c(237) ), but never used
  838. Xfputs returns value which is always ignored
  839. Xungetc returns value which is always ignored
  840. Xsprintf returns value which is always ignored
  841. Xalist defined( active.c(13) ), but never used
  842. Xendpwent returns value which is always ignored
  843. Xsignal returns value which is sometimes ignored
  844. Xfflush returns value which is sometimes ignored
  845. Xsubsub returns value which is sometimes ignored
  846. Xstrcpy returns value which is sometimes ignored
  847. Xseen returns value which is sometimes ignored
  848. Xfclose returns value which is always ignored
  849. X_flsbuf returns value which is always ignored
  850. Xsystem returns value which is always ignored
  851. Xstrncpy returns value which is always ignored
  852. Xclose returns value which is always ignored
  853. Xfseek returns value which is always ignored
  854. Xgtty returns value which is always ignored
  855. Xstty returns value which is always ignored
  856. Xnewstr6 defined( funcs.c(81) ), but never used
  857. Xngsquash defined( funcs.c(196) ), but never used
  858. Xgetunique defined( funcs.c(220) ), but never used
  859. Xchown returns value which is always ignored
  860. Xunlink returns value which is sometimes ignored
  861. Xrconvg defined( funcs.c(350) ), but never used
  862. Xreadln defined( funcs.c(392) ), but never used
  863. Xapplyng defined( funcs.c(420) ), but never used
  864. Xgetseq defined( active.c(23) ), but never used
  865. Xsetlow defined( active.c(141) ), but never used
  866. Xinitgrp defined( active.c(167) ), but never used
  867. Xcancel defined( history.c(73) ), but never used
  868. Xchkhist defined( history.c(86) ), but never used
  869. Xopenhist defined( history.c(140) ), but never used
  870. Xwritehist defined( history.c(156) ), but never used
  871. Xclosehist defined( history.c(165) ), but never used
  872. X
  873. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(149)
  874. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(150)
  875. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(151)
  876. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(152)
  877. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(227)
  878. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(228)
  879. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(229)
  880. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(230)
  881. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(1158)
  882. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(1159)
  883. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(1160)
  884. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(1161)
  885. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(1166)
  886. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(1167)
  887. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(1168)
  888. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  readnews.c(1169)
  889. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  newsrc.c(251)
  890. Xsignal, arg. 2 used inconsistently    llib-lc:llib-lc(117)  ::  newsrc.c(252)
  891. END_OF_FILE
  892. if test 5157 -ne `wc -c <'rna/readnews.lint'`; then
  893.     echo shar: \"'rna/readnews.lint'\" unpacked with wrong size!
  894. fi
  895. # end of 'rna/readnews.lint'
  896. fi
  897. if test -f 'rnews/control.c' -a "${1}" != "-c" ; then 
  898.   echo shar: Will not clobber existing file \"'rnews/control.c'\"
  899. else
  900. echo shar: Extracting \"'rnews/control.c'\" \(6110 characters\)
  901. sed "s/^X//" >'rnews/control.c' <<'END_OF_FILE'
  902. X/*
  903. X * Implement the control messages.
  904. X * These are fairly infrequent and can afford to be done by
  905. X * separate programs.  They are:
  906. X *
  907. X * cancel message-ID        restricted to Sender: else From: or root, in theory
  908. X *
  909. X * newgroup groupname        restrict this, in theory
  910. X * rmgroup groupname        allow some local control over this
  911. X *
  912. X * sendsys            to Reply-To: else From:
  913. X * senduuname            to Reply-To: else From:
  914. X * version            to Reply-To: else From: (NB seismo)
  915. X *
  916. X * ihave message-ID-list remotesys    some day ...
  917. X * sendme message-ID-list remotesys    some day ...
  918. X *
  919. X * TODO: one shell file only for controls? or more common scripts?
  920. X */
  921. X
  922. X#include <stdio.h>
  923. X#include <ctype.h>
  924. X#ifdef lint
  925. X#include <sgtty.h>            /* for TIOCNOTTY, if present */
  926. X#ifdef TIOCNOTTY            /* 4.2BSD or later berklix */
  927. X#include <sys/wait.h>
  928. X#endif                    /* TIOCNOTTY */
  929. X#endif                    /* lint */
  930. X#include <sys/types.h>
  931. X
  932. X#include "news.h"
  933. X#include "newspaths.h"
  934. X#include "headers.h"
  935. X#include "history.h"
  936. X
  937. X#define SUBDIR "ctl"            /* holds shell scripts */
  938. X
  939. X#ifndef USENET
  940. X#define USENET "usenet"            /* mail address of usenet admin. */
  941. X#endif
  942. X
  943. X/*
  944. X * These are shell meta-characters, except for /, which is included
  945. X * since it allows people to escape from the control directory.
  946. X */
  947. X#define SHELLMETAS "<>|&;({$=*?[`'\"/"
  948. X
  949. X/*
  950. X * Implement control message specified in hdrs.
  951. X * Because newgroup and rmgroup may modify the active file, for example,
  952. X * we must flush in-core caches to disk first and reload them afterward.
  953. X * TODO: pass header values to scripts as args or in environ,
  954. X *    as NEWS* variables.
  955. X */
  956. Xint
  957. Xctlmsg(hdrs)
  958. Xstruct headers *hdrs;
  959. X{
  960. X    int status = ST_OKAY, pid, deadpid;
  961. X#ifdef lint
  962. X#ifdef TIOCNOTTY            /* 4.2BSD or later berklix */
  963. X    union wait wstatus;
  964. X#else                    /* TIOCNOTTY */
  965. X    int wstatus;
  966. X#endif                    /* TIOCNOTTY */
  967. X#else                    /* lint */
  968. X    int wstatus;
  969. X#endif                    /* lint */
  970. X    char *inname = hdrs->h_tmpf, *ctlcmd = hdrs->h_ctlcmd;
  971. X    static char nmcancel[] = "cancel ";
  972. X
  973. X    /* process cancels in this process for speed and dbm access */
  974. X    if (STREQN(ctlcmd, nmcancel, STRLEN(nmcancel)))
  975. X        return cancelart(ctlcmd + STRLEN(nmcancel));
  976. X
  977. X    status |= synccaches();        /* sync in-core copies to disk */
  978. X    if ((pid = fork()) == 0) {    /* child process */
  979. X        int cmdstat;
  980. X        char *cmd;
  981. X
  982. X        /*
  983. X         * Enforce at least minimal security:
  984. X         * standardise the environment, including PATH and IFS -
  985. X         * a local addition to libc (TODO: do it by hand);
  986. X         * reject shell metacharacters in ctlcmd.
  987. X         */
  988. X        standard();            /* close most files, etc. */
  989. X        if (!safecmd(ctlcmd))
  990. X            _exit(1);        /* don't flush stdio buffers */
  991. X
  992. X        cmd = emalloc((unsigned)STRLEN("exec ") +
  993. X            strlen(libfile(SUBDIR)) + STRLEN(SFNDELIM) +
  994. X            strlen(ctlcmd) + STRLEN(" <") + strlen(inname) + 1);
  995. X        (void) sprintf(cmd, "exec %s/%s <%s", libfile(SUBDIR),
  996. X            ctlcmd, inname);
  997. X
  998. X        cmdstat = system(cmd);            /* punt */
  999. X        if (cmdstat != 0) {            /* intercepted */
  1000. X            char *mailcmd;
  1001. X            FILE *mailf;
  1002. X            extern char *progname;
  1003. X    
  1004. X            mailcmd = emalloc((unsigned)STRLEN("PATH=") +
  1005. X                STRLEN(STDPATH) + STRLEN(" mail ") +
  1006. X                STRLEN(USENET) + 1);
  1007. X            /*
  1008. X             * Honk at the usenet administrator &
  1009. X             * mark this article as dropped.
  1010. X             */
  1011. X            (void) sprintf(mailcmd, "PATH=%s mail %s",
  1012. X                STDPATH, USENET);
  1013. X            mailf = popen(mailcmd, "w");
  1014. X            if (mailf == NULL)
  1015. X                mailf = stderr;
  1016. X            (void) fprintf(mailf,
  1017. X            "%s: control message `%s' exited with status 0%o\n",
  1018. X                progname, cmd, cmdstat);
  1019. X            if (mailf != stderr)
  1020. X                (void) pclose(mailf);
  1021. X            free(mailcmd);
  1022. X            _exit(1);            /* don't flush */
  1023. X        }
  1024. X        free(cmd);
  1025. X        _exit(0);                /* don't flush */
  1026. X    }
  1027. X    while ((deadpid = wait(&wstatus)) != pid && deadpid != -1)
  1028. X        ;
  1029. X
  1030. X    /* wrong kid returned, fork failed or child screwed up? */
  1031. X    if (deadpid != pid || pid == -1
  1032. X#ifndef lint
  1033. X        || wstatus != 0
  1034. X#endif                        /* lint */
  1035. X        )
  1036. X        status |= ST_DROPPED;        /* admin got err.msg. by mail above */
  1037. X    status |= loadcaches();            /* reload in-core copies */
  1038. X    return status;
  1039. X}
  1040. X
  1041. Xstatic int
  1042. Xsafecmd(cmd)            /* true if it's safe to system(3) cmd */
  1043. Xchar *cmd;
  1044. X{
  1045. X    register char *s;
  1046. X
  1047. X    for (s = cmd; *s != '\0'; s++)
  1048. X        if (STREQN(s, "..", strlen("..")))
  1049. X            return NO;
  1050. X    for (s = SHELLMETAS; *s != '\0'; s++)
  1051. X        if (index(cmd, *s) != NULL)
  1052. X            return NO;
  1053. X    return YES;
  1054. X}
  1055. X
  1056. Xstatic int
  1057. Xcancelart(msgidstr)
  1058. Xchar *msgidstr;
  1059. X{
  1060. X    register char *wsp;
  1061. X    /* TODO: someday free this storage */
  1062. X    /* copy msgidstr into malloc'ed store */
  1063. X    register char *msgid = strsave(msgidstr);
  1064. X    int status = ST_OKAY;
  1065. X
  1066. X    /* skip leading whitespace in msgid */
  1067. X    while (*msgid != '\0' && isascii(*msgid) && isspace(*msgid))
  1068. X        ++msgid;
  1069. X
  1070. X    /* eliminate trailing whitespace in msgid */
  1071. X    for (wsp = msgid + strlen(msgid) - 1; wsp >= msgid &&
  1072. X        isascii(*wsp) && isspace(*wsp); --wsp)
  1073. X        *wsp = '\0';
  1074. X
  1075. X    /* cancel article if seen, else generate history entry for it */
  1076. X    if (alreadyseen(msgid)) {
  1077. X        char *histent, *filelist;
  1078. X
  1079. X        /*
  1080. X         * In theory (RFC 850), inews should verify that the
  1081. X         * user issuing the cancel (the Sender: of this
  1082. X         * article or From: if no Sender) is the Sender: or
  1083. X         * From: of the original article or the super-user on
  1084. X         * this machine.
  1085. X         *
  1086. X         * In practice, this is a lot of work and since
  1087. X         * anyone can forge news (and thus cancel anything),
  1088. X         * not worth the effort.
  1089. X         *
  1090. X         * Ignore ST_ACCESS since the article may have been
  1091. X         * cancelled before or may have a fake history entry
  1092. X         * because the cancel arrived before the article.
  1093. X         */
  1094. X        histent = gethistory(msgid);
  1095. X        if (histent != NULL &&
  1096. X            (filelist = findfiles(histent)) != NULL)
  1097. X            status |= snufffiles(filelist) & ~ST_ACCESS;
  1098. X    } else {
  1099. X        /*
  1100. X         * Generate a history file entry for the cancelled article
  1101. X         * in case it arrives after the cancel control.
  1102. X         * The history file entry will cause the cancelled article
  1103. X         * to be rejected as a duplicate.
  1104. X         *
  1105. X         * Forge up the necessary header struct members
  1106. X         * (see history() for details).
  1107. X         */
  1108. X        static struct headers hdrs;    /* static to zero parts */
  1109. X
  1110. X        hdrs.h_msgid = msgid;
  1111. X        /* any unlinkable file is OK, so use root */
  1112. X        (void) strcpy(hdrs.h_files, "/");
  1113. X        hdrs.h_expiry = "-";        /* use default expiry */
  1114. X        status |= history(&hdrs);
  1115. X        (void) putchar('\n');        /* end log line */
  1116. X    }
  1117. X    return status;
  1118. X}
  1119. END_OF_FILE
  1120. if test 6110 -ne `wc -c <'rnews/control.c'`; then
  1121.     echo shar: \"'rnews/control.c'\" unpacked with wrong size!
  1122. fi
  1123. # end of 'rnews/control.c'
  1124. fi
  1125. if test -f 'rnews/inews' -a "${1}" != "-c" ; then 
  1126.   echo shar: Will not clobber existing file \"'rnews/inews'\"
  1127. else
  1128. echo shar: Extracting \"'rnews/inews'\" \(6183 characters\)
  1129. sed "s/^X//" >'rnews/inews' <<'END_OF_FILE'
  1130. X#! /bin/sh
  1131. X# inews [-p] [-d k] [-x site] [-hMD] [-t subj] [-n ng] [-e exp] [-F ref] \
  1132. X#  [-d dist] [-a mod] [-f from] [-o org] [-C ng] [file...] - inject news:
  1133. X#    censor locally-posted article and field the "inews -C" kludge;
  1134. X#    munge the articles, enforce bogus and pathetic attempts at
  1135. X#    Usenet security, generate lotsa silly headers.
  1136. XNEWSCTL=${NEWSCTL-/usr/lib/news}    # export NEWSCTL
  1137. XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}    # export NEWSBIN
  1138. XNEWSARTS=${NEWSARTS-/usr/spool/news}    # export NEWSARTS
  1139. XPATH=$NEWSCTL:$NEWSBIN:$NEWSBIN/relay:/bin:/usr/bin:/usr/ucb; export PATH
  1140. XPASSEDFROM='';    export PASSEDFROM    # passed to anne.jones in environ.
  1141. Xallowed=geoff            # tailor: local news admin (may be "")
  1142. Xdebug=''            # flags
  1143. Xexclusion=''
  1144. Xhdrspresent=no
  1145. Xwhoami=/tmp/in$$who        # just created to determine effective uid
  1146. Xinput=/tmp/in$$in        # uncensored input
  1147. Xinhdrs=/tmp/in$$hdr        # generated by tear: headers
  1148. Xinbody=/tmp/in$$body        # generated by tear: body
  1149. Xcensart=/tmp/in$$cens        # censored input
  1150. Xnglist=/tmp/in$$ngs        # newsgroups: list
  1151. Xmodroute=/tmp/in$$route        # route to moderator's forwarder
  1152. Xrmlist="$inhdrs $inbody $input $censart $nglist $modroute"
  1153. X
  1154. Xumask 2
  1155. Xtrap '' 1 2 15            # ignore signals to avoid losing articles
  1156. X
  1157. X# "inews -p": invoke rnews
  1158. Xcase "$1" in
  1159. X-p)
  1160. X    shift
  1161. X    exec rnews $*        # rnews, bailing out at or near line 1
  1162. X    ;;
  1163. Xesac
  1164. X
  1165. X# parse arguments: for options, cat headers onto $input; cat files onto $input
  1166. X>$input
  1167. Xwhile :
  1168. Xdo
  1169. X    case $# in
  1170. X    0)    break ;;        # arguments exhausted
  1171. X    esac
  1172. X
  1173. X    case "$1" in
  1174. X    -debug)    shift; debug="$1" ;;        # peculiar to C news
  1175. X    -x)    shift; exclusion="-x $1" ;;    # you're welcome, erik (2.11)
  1176. X    -h)    hdrspresent=yes ;;
  1177. X    -M)    # TODO: what's this *really* do? dunno, find out
  1178. X        ;;
  1179. X    -D)    # obsolete, undocumented: meant "don't check for recordings".
  1180. X        # last present in B 2.10.1, invoked by readnews for followups.
  1181. X        ;;
  1182. X    -t)    shift; echo "Subject: $1" >>$input ;;
  1183. X    -n)    shift; echo "Newsgroups: $1" >>$input ;;
  1184. X    -e)    shift; echo "Expires: $1" >>$input ;;
  1185. X    -F)    # undocumented in B 2.10.1, documented in B 2.11.
  1186. X        shift; echo "References: $1" >>$input ;;
  1187. X    -d)    shift; echo "Distribution: $1" >>$input ;;
  1188. X    -a)    shift; echo "Approved: $1" >>$input ;;
  1189. X
  1190. X    # pass next options as environment variables to anne.jones
  1191. X    -f)    shift; PASSEDFROM="$1" ;;    # complex due to Sender:
  1192. X    -o)    shift; ORGANIZATION="$1"; export ORGANIZATION ;;
  1193. X
  1194. X    -[cC])
  1195. X        # megakludge-o-rama
  1196. X        # first, permit only to super-users
  1197. X        >$whoami
  1198. X        case "`ls -l $whoami | awk '{print $3}'`" in
  1199. X        root|$allowed)    : a winner ;;
  1200. X        *)
  1201. X            echo "$0: only super-users may create news groups" >&2
  1202. X            exit 1
  1203. X            ;;
  1204. X        esac
  1205. X        rm -f $whoami
  1206. X        case "$1" in
  1207. X        -c)    echo "Distribution: general" >>$input ;;
  1208. X        esac
  1209. X        shift            # skip -C
  1210. X        case "$1" in
  1211. X        *.*.*)    ng=news.announce ;;
  1212. X        *.*)    ng="$1" ;;
  1213. X        *)    ng="$1.$1" ;;
  1214. X        esac
  1215. X        cat <<! >>$input        # generate -C header
  1216. XNewsgroups: $ng.ctl
  1217. XSubject: cmsg newgroup $1
  1218. XControl: newgroup $1
  1219. X
  1220. Xcreated by inews -C or inews -c.
  1221. X!
  1222. X        ;;
  1223. X    -*)
  1224. X        echo "$0: bad option $1" >&2
  1225. X        exit 1
  1226. X        ;;
  1227. X    *)
  1228. X        case "$hdrspresent" in
  1229. X        no)    echo "" >>$input; hdrspresent=yes ;;
  1230. X        esac
  1231. X        cat "$1" >>$input        # is a filename; append file
  1232. X        fileseen=yes
  1233. X        ;;
  1234. X    esac
  1235. X    shift        # pass option or filename (any value was done above)
  1236. Xdone
  1237. X
  1238. X# if no files named, read stdin
  1239. Xcase "$fileseen" in
  1240. Xyes)    ;;
  1241. X*)
  1242. X    case "$hdrspresent" in
  1243. X    no)    echo "" >>$input; hdrspresent=yes ;;
  1244. X    esac
  1245. X    # capture incoming news in case inews fails
  1246. X    if cat >>$input; then
  1247. X        : far out
  1248. X    else
  1249. X        echo "$0: lost news; cat status $?" >&2
  1250. X        exit 1
  1251. X    fi
  1252. X    ;;
  1253. Xesac
  1254. X
  1255. X# run the remainder in the background for the benefit of impatient people
  1256. X( # mary.brown <$input >$censart    # censor the headers, glue on .signature
  1257. Xtear /tmp/in$$ <$input        # output in $inhdrs and $inbody
  1258. X# bounce zero-line articles (bad idea for control messages)
  1259. X#if test ! -s $inbody; then
  1260. X#    echo "$0: no article body" >&2
  1261. X#    rm -f $rmlist
  1262. X#    exit 1
  1263. X#fi
  1264. X# post with new headers and .signature
  1265. X(anne.jones <$inhdrs        # bash headers
  1266. X tr -d '\1-\7\13\14\16-\37' <$inbody # strip invisible chars from body, a la B news
  1267. X if test -r $HOME/.signature; then
  1268. X    echo "-- "; sed 4q $HOME/.signature    # glue on first bit of signature
  1269. X fi) >$censart
  1270. X
  1271. X# to post or to mail? that is the question; whether 'tis nobler in the mind
  1272. X# to suffer the slings and arrows of outrageous mailers ... Bill Shakespeare
  1273. Xsed -n '/^Newsgroups:[     ]/{
  1274. Xs/^Newsgroups:[     ]*\(.*\)$/\1/p
  1275. Xq
  1276. X}' <$inhdrs >$nglist
  1277. Xegrep "^(` sed 's/\./\\\\./
  1278. Xs/,/|/' <$nglist `) " $NEWSCTL/active |
  1279. X    while read ng high low flag    # look at next group's active entry
  1280. X    do
  1281. X        case "$flag" in
  1282. X        n)
  1283. X            echo "$0: bugger off, $ng may not be posted to." >&2
  1284. X            exit 1
  1285. X            ;;
  1286. X        m)
  1287. X            if grep -s '^Approved:[     ]' $inhdrs; then
  1288. X                rm $modroute        # just post normally
  1289. X            else
  1290. X                # un-Approved: mail it to the moderator(s).
  1291. X                echo "%s" >$modroute    # in case no route
  1292. X                # look for route for this group
  1293. X                while read ngpat route
  1294. X                do
  1295. X                    # a dreadful B 2.11 hack:
  1296. X                    # backbone|internet == all
  1297. X                    case "$ngpat" in
  1298. X                    backbone|internet)    ngpat="all" ;;
  1299. X                    esac
  1300. X                    if gngp -a "$ngpat" $nglist >/dev/null; then
  1301. X                        echo "$route" >$modroute
  1302. X                        break    # take only 1st match
  1303. X                    fi
  1304. X                done <$NEWSCTL/mailpaths
  1305. X            fi
  1306. X            # ngpat and route are not set here, damn it!
  1307. X            if test -s $modroute; then
  1308. X                # a mod group! mail article to this moderator
  1309. X                sendnews `sed "s/%s/\`echo $ng | tr . - \`/" \
  1310. X                    $modroute` <$censart
  1311. X                rm -f $rmlist
  1312. X                exit 0
  1313. X            # $censart is used rather than a pipe to work around a bug in the 4.2 sh
  1314. X            # which made it sometimes return the wrong exit status (that of anne.jones).
  1315. X            elif serverrnews $exclusion -d "$debug" <$censart    # -s $NEWSARTS -l $NEWSCTL
  1316. X            then
  1317. X                rm -f $rmlist        # far out, it worked
  1318. X                exit 0
  1319. X            else
  1320. X                status=$?
  1321. X                echo "$0: failed news in $input; inews status $status" >&2
  1322. X                exit $status
  1323. X            fi
  1324. X            ;;
  1325. X        y)
  1326. X            # $censart is used rather than a pipe to work around a bug in the 4.2 sh
  1327. X            # which made it sometimes return the wrong exit status (that of anne.jones).
  1328. X            if serverrnews $exclusion -d "$debug" <$censart    # -s $NEWSARTS -l $NEWSCTL
  1329. X            then
  1330. X                rm -f $rmlist        # far out, it worked
  1331. X                exit 0
  1332. X            else
  1333. X                status=$?
  1334. X                echo "$0: failed news in $input; inews status $status" >&2
  1335. X                exit $status
  1336. X            fi
  1337. X            ;;
  1338. X        esac
  1339. X    done
  1340. X) &
  1341. END_OF_FILE
  1342. if test 6183 -ne `wc -c <'rnews/inews'`; then
  1343.     echo shar: \"'rnews/inews'\" unpacked with wrong size!
  1344. fi
  1345. # end of 'rnews/inews'
  1346. fi
  1347. if test -f 'rnews/sh/inews' -a "${1}" != "-c" ; then 
  1348.   echo shar: Will not clobber existing file \"'rnews/sh/inews'\"
  1349. else
  1350. echo shar: Extracting \"'rnews/sh/inews'\" \(6183 characters\)
  1351. sed "s/^X//" >'rnews/sh/inews' <<'END_OF_FILE'
  1352. X#! /bin/sh
  1353. X# inews [-p] [-d k] [-x site] [-hMD] [-t subj] [-n ng] [-e exp] [-F ref] \
  1354. X#  [-d dist] [-a mod] [-f from] [-o org] [-C ng] [file...] - inject news:
  1355. X#    censor locally-posted article and field the "inews -C" kludge;
  1356. X#    munge the articles, enforce bogus and pathetic attempts at
  1357. X#    Usenet security, generate lotsa silly headers.
  1358. XNEWSCTL=${NEWSCTL-/usr/lib/news}    # export NEWSCTL
  1359. XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}    # export NEWSBIN
  1360. XNEWSARTS=${NEWSARTS-/usr/spool/news}    # export NEWSARTS
  1361. XPATH=$NEWSCTL:$NEWSBIN:$NEWSBIN/relay:/bin:/usr/bin:/usr/ucb; export PATH
  1362. XPASSEDFROM='';    export PASSEDFROM    # passed to anne.jones in environ.
  1363. Xallowed=geoff            # tailor: local news admin (may be "")
  1364. Xdebug=''            # flags
  1365. Xexclusion=''
  1366. Xhdrspresent=no
  1367. Xwhoami=/tmp/in$$who        # just created to determine effective uid
  1368. Xinput=/tmp/in$$in        # uncensored input
  1369. Xinhdrs=/tmp/in$$hdr        # generated by tear: headers
  1370. Xinbody=/tmp/in$$body        # generated by tear: body
  1371. Xcensart=/tmp/in$$cens        # censored input
  1372. Xnglist=/tmp/in$$ngs        # newsgroups: list
  1373. Xmodroute=/tmp/in$$route        # route to moderator's forwarder
  1374. Xrmlist="$inhdrs $inbody $input $censart $nglist $modroute"
  1375. X
  1376. Xumask 2
  1377. Xtrap '' 1 2 15            # ignore signals to avoid losing articles
  1378. X
  1379. X# "inews -p": invoke rnews
  1380. Xcase "$1" in
  1381. X-p)
  1382. X    shift
  1383. X    exec rnews $*        # rnews, bailing out at or near line 1
  1384. X    ;;
  1385. Xesac
  1386. X
  1387. X# parse arguments: for options, cat headers onto $input; cat files onto $input
  1388. X>$input
  1389. Xwhile :
  1390. Xdo
  1391. X    case $# in
  1392. X    0)    break ;;        # arguments exhausted
  1393. X    esac
  1394. X
  1395. X    case "$1" in
  1396. X    -debug)    shift; debug="$1" ;;        # peculiar to C news
  1397. X    -x)    shift; exclusion="-x $1" ;;    # you're welcome, erik (2.11)
  1398. X    -h)    hdrspresent=yes ;;
  1399. X    -M)    # TODO: what's this *really* do? dunno, find out
  1400. X        ;;
  1401. X    -D)    # obsolete, undocumented: meant "don't check for recordings".
  1402. X        # last present in B 2.10.1, invoked by readnews for followups.
  1403. X        ;;
  1404. X    -t)    shift; echo "Subject: $1" >>$input ;;
  1405. X    -n)    shift; echo "Newsgroups: $1" >>$input ;;
  1406. X    -e)    shift; echo "Expires: $1" >>$input ;;
  1407. X    -F)    # undocumented in B 2.10.1, documented in B 2.11.
  1408. X        shift; echo "References: $1" >>$input ;;
  1409. X    -d)    shift; echo "Distribution: $1" >>$input ;;
  1410. X    -a)    shift; echo "Approved: $1" >>$input ;;
  1411. X
  1412. X    # pass next options as environment variables to anne.jones
  1413. X    -f)    shift; PASSEDFROM="$1" ;;    # complex due to Sender:
  1414. X    -o)    shift; ORGANIZATION="$1"; export ORGANIZATION ;;
  1415. X
  1416. X    -[cC])
  1417. X        # megakludge-o-rama
  1418. X        # first, permit only to super-users
  1419. X        >$whoami
  1420. X        case "`ls -l $whoami | awk '{print $3}'`" in
  1421. X        root|$allowed)    : a winner ;;
  1422. X        *)
  1423. X            echo "$0: only super-users may create news groups" >&2
  1424. X            exit 1
  1425. X            ;;
  1426. X        esac
  1427. X        rm -f $whoami
  1428. X        case "$1" in
  1429. X        -c)    echo "Distribution: general" >>$input ;;
  1430. X        esac
  1431. X        shift            # skip -C
  1432. X        case "$1" in
  1433. X        *.*.*)    ng=news.announce ;;
  1434. X        *.*)    ng="$1" ;;
  1435. X        *)    ng="$1.$1" ;;
  1436. X        esac
  1437. X        cat <<! >>$input        # generate -C header
  1438. XNewsgroups: $ng.ctl
  1439. XSubject: cmsg newgroup $1
  1440. XControl: newgroup $1
  1441. X
  1442. Xcreated by inews -C or inews -c.
  1443. X!
  1444. X        ;;
  1445. X    -*)
  1446. X        echo "$0: bad option $1" >&2
  1447. X        exit 1
  1448. X        ;;
  1449. X    *)
  1450. X        case "$hdrspresent" in
  1451. X        no)    echo "" >>$input; hdrspresent=yes ;;
  1452. X        esac
  1453. X        cat "$1" >>$input        # is a filename; append file
  1454. X        fileseen=yes
  1455. X        ;;
  1456. X    esac
  1457. X    shift        # pass option or filename (any value was done above)
  1458. Xdone
  1459. X
  1460. X# if no files named, read stdin
  1461. Xcase "$fileseen" in
  1462. Xyes)    ;;
  1463. X*)
  1464. X    case "$hdrspresent" in
  1465. X    no)    echo "" >>$input; hdrspresent=yes ;;
  1466. X    esac
  1467. X    # capture incoming news in case inews fails
  1468. X    if cat >>$input; then
  1469. X        : far out
  1470. X    else
  1471. X        echo "$0: lost news; cat status $?" >&2
  1472. X        exit 1
  1473. X    fi
  1474. X    ;;
  1475. Xesac
  1476. X
  1477. X# run the remainder in the background for the benefit of impatient people
  1478. X( # mary.brown <$input >$censart    # censor the headers, glue on .signature
  1479. Xtear /tmp/in$$ <$input        # output in $inhdrs and $inbody
  1480. X# bounce zero-line articles (bad idea for control messages)
  1481. X#if test ! -s $inbody; then
  1482. X#    echo "$0: no article body" >&2
  1483. X#    rm -f $rmlist
  1484. X#    exit 1
  1485. X#fi
  1486. X# post with new headers and .signature
  1487. X(anne.jones <$inhdrs        # bash headers
  1488. X tr -d '\1-\7\13\14\16-\37' <$inbody # strip invisible chars from body, a la B news
  1489. X if test -r $HOME/.signature; then
  1490. X    echo "-- "; sed 4q $HOME/.signature    # glue on first bit of signature
  1491. X fi) >$censart
  1492. X
  1493. X# to post or to mail? that is the question; whether 'tis nobler in the mind
  1494. X# to suffer the slings and arrows of outrageous mailers ... Bill Shakespeare
  1495. Xsed -n '/^Newsgroups:[     ]/{
  1496. Xs/^Newsgroups:[     ]*\(.*\)$/\1/p
  1497. Xq
  1498. X}' <$inhdrs >$nglist
  1499. Xegrep "^(` sed 's/\./\\\\./
  1500. Xs/,/|/' <$nglist `) " $NEWSCTL/active |
  1501. X    while read ng high low flag    # look at next group's active entry
  1502. X    do
  1503. X        case "$flag" in
  1504. X        n)
  1505. X            echo "$0: bugger off, $ng may not be posted to." >&2
  1506. X            exit 1
  1507. X            ;;
  1508. X        m)
  1509. X            if grep -s '^Approved:[     ]' $inhdrs; then
  1510. X                rm $modroute        # just post normally
  1511. X            else
  1512. X                # un-Approved: mail it to the moderator(s).
  1513. X                echo "%s" >$modroute    # in case no route
  1514. X                # look for route for this group
  1515. X                while read ngpat route
  1516. X                do
  1517. X                    # a dreadful B 2.11 hack:
  1518. X                    # backbone|internet == all
  1519. X                    case "$ngpat" in
  1520. X                    backbone|internet)    ngpat="all" ;;
  1521. X                    esac
  1522. X                    if gngp -a "$ngpat" $nglist >/dev/null; then
  1523. X                        echo "$route" >$modroute
  1524. X                        break    # take only 1st match
  1525. X                    fi
  1526. X                done <$NEWSCTL/mailpaths
  1527. X            fi
  1528. X            # ngpat and route are not set here, damn it!
  1529. X            if test -s $modroute; then
  1530. X                # a mod group! mail article to this moderator
  1531. X                sendnews `sed "s/%s/\`echo $ng | tr . - \`/" \
  1532. X                    $modroute` <$censart
  1533. X                rm -f $rmlist
  1534. X                exit 0
  1535. X            # $censart is used rather than a pipe to work around a bug in the 4.2 sh
  1536. X            # which made it sometimes return the wrong exit status (that of anne.jones).
  1537. X            elif serverrnews $exclusion -d "$debug" <$censart    # -s $NEWSARTS -l $NEWSCTL
  1538. X            then
  1539. X                rm -f $rmlist        # far out, it worked
  1540. X                exit 0
  1541. X            else
  1542. X                status=$?
  1543. X                echo "$0: failed news in $input; inews status $status" >&2
  1544. X                exit $status
  1545. X            fi
  1546. X            ;;
  1547. X        y)
  1548. X            # $censart is used rather than a pipe to work around a bug in the 4.2 sh
  1549. X            # which made it sometimes return the wrong exit status (that of anne.jones).
  1550. X            if serverrnews $exclusion -d "$debug" <$censart    # -s $NEWSARTS -l $NEWSCTL
  1551. X            then
  1552. X                rm -f $rmlist        # far out, it worked
  1553. X                exit 0
  1554. X            else
  1555. X                status=$?
  1556. X                echo "$0: failed news in $input; inews status $status" >&2
  1557. X                exit $status
  1558. X            fi
  1559. X            ;;
  1560. X        esac
  1561. X    done
  1562. X) &
  1563. END_OF_FILE
  1564. if test 6183 -ne `wc -c <'rnews/sh/inews'`; then
  1565.     echo shar: \"'rnews/sh/inews'\" unpacked with wrong size!
  1566. fi
  1567. # end of 'rnews/sh/inews'
  1568. fi
  1569. echo shar: End of archive 8 \(of 14\).
  1570. ##  End of shell archive.
  1571. exit 0
  1572.